﻿// Decompiled with JetBrains decompiler
// Type: UnityEngine.Profiling.Memory.Experimental.MemoryProfiler
// Assembly: UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E6AE6B5A-2752-4B07-9528-C8B77C62CE79
// Assembly location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.dll
// XML documentation location: C:\Users\windys\Unity\2021.3.39f1c1\Editor\Data\Managed\UnityEngine\UnityEngine.CoreModule.xml

using System;
using System.Runtime.CompilerServices;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine.Bindings;
using UnityEngine.Profiling.Experimental;
using UnityEngine.Scripting;

#nullable disable
namespace UnityEngine.Profiling.Memory.Experimental
{
  /// <summary>
  ///   <para>Memory profiling API container class.</para>
  /// </summary>
  [NativeHeader("Modules/Profiler/Runtime/MemorySnapshotManager.h")]
  public sealed class MemoryProfiler
  {
    private static bool isCompiling;

    private static event Action<string, bool> m_SnapshotFinished;

    private static event Action<string, bool, DebugScreenCapture> m_SaveScreenshotToDisk;

    public static event Action<MetaData> createMetaData;

    internal static void StartedCompilationCallback(object msg)
    {
      MemoryProfiler.isCompiling = true;
    }

    internal static void FinishedCompilationCallback(object msg)
    {
      MemoryProfiler.isCompiling = false;
    }

    [StaticAccessor("profiling::memory::GetMemorySnapshotManager()", StaticAccessorType.Dot)]
    [NativeMethod("StartOperation")]
    [NativeConditional("ENABLE_PROFILER")]
    [MethodImpl(MethodImplOptions.InternalCall)]
    private static extern void StartOperation(
      uint captureFlag,
      bool requestScreenshot,
      string path,
      bool isRemote);

    public static void TakeSnapshot(
      string path,
      Action<string, bool> finishCallback,
      CaptureFlags captureFlags = CaptureFlags.ManagedObjects | CaptureFlags.NativeObjects)
    {
      MemoryProfiler.TakeSnapshot(path, finishCallback, (Action<string, bool, DebugScreenCapture>) null, captureFlags);
    }

    public static void TakeSnapshot(
      string path,
      Action<string, bool> finishCallback,
      Action<string, bool, DebugScreenCapture> screenshotCallback,
      CaptureFlags captureFlags = CaptureFlags.ManagedObjects | CaptureFlags.NativeObjects)
    {
      if (MemoryProfiler.isCompiling)
        Debug.LogError((object) "Canceling snapshot, there is a compilation in progress.");
      else if (MemoryProfiler.m_SnapshotFinished != null)
      {
        Debug.LogWarning((object) "Canceling snapshot, there is another snapshot in progress.");
        finishCallback(path, false);
      }
      else
      {
        MemoryProfiler.m_SnapshotFinished += finishCallback;
        MemoryProfiler.m_SaveScreenshotToDisk += screenshotCallback;
        MemoryProfiler.StartOperation((uint) captureFlags, MemoryProfiler.m_SaveScreenshotToDisk != null, path, false);
      }
    }

    public static void TakeTempSnapshot(
      Action<string, bool> finishCallback,
      CaptureFlags captureFlags = CaptureFlags.ManagedObjects | CaptureFlags.NativeObjects)
    {
      string[] strArray = Application.dataPath.Split('/');
      MemoryProfiler.TakeSnapshot(Application.temporaryCachePath + "/" + strArray[strArray.Length - 2] + ".snap", finishCallback, captureFlags);
    }

    [RequiredByNativeCode]
    private static byte[] PrepareMetadata()
    {
      if (MemoryProfiler.createMetaData == null)
        return new byte[0];
      MetaData metaData = new MetaData();
      MemoryProfiler.createMetaData(metaData);
      if (metaData.content == null)
        metaData.content = "";
      if (metaData.platform == null)
        metaData.platform = "";
      byte[] array = new byte[2 * metaData.content.Length + 2 * metaData.platform.Length + 12];
      int offset = 0;
      int byteArray1 = MemoryProfiler.WriteIntToByteArray(array, offset, metaData.content.Length);
      int byteArray2 = MemoryProfiler.WriteStringToByteArray(array, byteArray1, metaData.content);
      int byteArray3 = MemoryProfiler.WriteIntToByteArray(array, byteArray2, metaData.platform.Length);
      MemoryProfiler.WriteStringToByteArray(array, byteArray3, metaData.platform);
      return array;
    }

    internal static unsafe int WriteIntToByteArray(byte[] array, int offset, int value)
    {
      byte* numPtr = (byte*) &value;
      array[offset++] = *numPtr;
      array[offset++] = numPtr[1];
      array[offset++] = numPtr[2];
      array[offset++] = numPtr[3];
      return offset;
    }

    internal static unsafe int WriteStringToByteArray(byte[] array, int offset, string value)
    {
      if (value.Length != 0)
      {
        string str = value;
        char* chPtr1 = (char*) str;
        if ((IntPtr) chPtr1 != IntPtr.Zero)
          chPtr1 += RuntimeHelpers.OffsetToStringData;
        char* chPtr2 = chPtr1;
        for (char* chPtr3 = chPtr1 + value.Length; chPtr2 != chPtr3; ++chPtr2)
        {
          for (int index = 0; index < 2; ++index)
            array[offset++] = *(byte*) ((IntPtr) chPtr2 + index);
        }
        str = (string) null;
      }
      return offset;
    }

    [RequiredByNativeCode]
    private static void FinalizeSnapshot(string path, bool result)
    {
      if (MemoryProfiler.m_SnapshotFinished == null)
        return;
      Action<string, bool> snapshotFinished = MemoryProfiler.m_SnapshotFinished;
      MemoryProfiler.m_SnapshotFinished = (Action<string, bool>) null;
      snapshotFinished(path, result);
    }

    [RequiredByNativeCode]
    private static unsafe void SaveScreenshotToDisk(
      string path,
      bool result,
      IntPtr pixelsPtr,
      int pixelsCount,
      TextureFormat format,
      int width,
      int height)
    {
      if (MemoryProfiler.m_SaveScreenshotToDisk == null)
        return;
      Action<string, bool, DebugScreenCapture> screenshotToDisk = MemoryProfiler.m_SaveScreenshotToDisk;
      MemoryProfiler.m_SaveScreenshotToDisk = (Action<string, bool, DebugScreenCapture>) null;
      DebugScreenCapture debugScreenCapture = new DebugScreenCapture();
      if (result)
      {
        NativeArray<byte> nativeArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray<byte>(pixelsPtr.ToPointer(), pixelsCount, Allocator.Persistent);
        debugScreenCapture.rawImageDataReference = nativeArray;
        debugScreenCapture.height = height;
        debugScreenCapture.width = width;
        debugScreenCapture.imageFormat = format;
      }
      screenshotToDisk(path, result, debugScreenCapture);
    }
  }
}
